// Global constants.
var GAME = {
  gameFps: 40, // ms.
  playgroundWidth: 960,
  playgroundHeight: 385,
  fieldPadding: 5 // px padding all around screen edges.
};

var PADDLE = {
  width: 120,
  height: 10,
  backgroundColor: "#000"
};

var BALL = {
  speed: 8, //px per refresh
  directionX: 1,
  directionY: 1,
  backgroundColor: "#00F",
  width: 20,
  height: 20,
  x: 470,
  y: 182
};

// Model classes.
jQuery.extend({
  Model: function(){
    console.log(".model class init");
    // Class init.
    var _this = this;
    var _listeners = [];

    // Private methods.

    // Public methods.

    // Bindings.

  }
});

// View classes.
jQuery.extend({
  Field: function(field) {
    console.log(".field class init");

    // Class init.
    var _this = this;
    var _listeners = [];

    field.css("width", GAME.playgroundWidth).css("height", GAME.playgroundHeight).css("background-color", "#818181").
        css("left", "0");

    // Ball init.
    var ball = field.find("#ball");

    ball.css("width", BALL.width).css("height", BALL.height).css("position", "absolute").
        css("top", BALL.y).css("left", BALL.x).css("background-color", BALL.backgroundColor);

    // Paddle init.
    var paddle = field.find("#paddle");

    paddle.css("width", PADDLE.width).css("height", PADDLE.height).
        css("background-color", PADDLE.backgroundColor).css("position", "absolute").
        css("top", GAME.playgroundHeight - (GAME.fieldPadding + PADDLE.height)).css("left", "420px");

    // Private methods.
    // TODO: imeplement paddle movement by accelerometer.
    var movePaddle = function(event) {
      var xPos = event.pageX;
      if (xPos + PADDLE.width > GAME.playgroundWidth) {
        xPos = GAME.playgroundWidth - PADDLE.width;
      }

      paddle.css("left", xPos);
    };

    // Public methods.
    this.getBallRect = function() {
      return {x: ball.position().left, y: ball.position().top,
          width: ball.width(), height: ball.height()};
    };

    this.setBallPos = function(value) {
      if (value.left) {
        ball.css("left", value.left);
      }
      if (value.right) {
        ball.css("right", value.right);
      }
      if (value.top) {
        ball.css("top", value.top);
      }
      if (value.bottom) {
        ball.css("bottom", value.bottom);
      }
    };

    this.getPaddleRect = function() {
      return {x: paddle.position().left, y: paddle.position().top,
          width: paddle.width(), height: paddle.height()};
    };

    // Bindings.
    field.live("vmousemove", movePaddle);

  }
});

// Controller classes.
jQuery.extend({
  Controller: function(view, model){
    console.log(".controller class init");
    // Class init.
    var _this = this;
    var _updateInterval;

    // Private methods.
    var updateGame = function() {
      updateBallPosition();
    };

    var updateBallPosition = function() {
      var ballRect = view.getBallRect();

      // Check bottom bound..
      if (ballRect.y > GAME.playgroundHeight - BALL.height) {
        // TODO: implement scoring functionality + new round start.
        BALL.directionY = -1;
        //_this.stopGame();
        //return false;
      }
      // Check top bound.
      if (ballRect.y <= 0) {
        // TODO: implement sending ball position to server hide ball.
        BALL.directionY = 1;
      }
      // Check right bound and change direction if needed.
      if (ballRect.x > GAME.playgroundWidth - BALL.width) {
        BALL.directionX = -1;
      }
      // Check left bound and change direction if needed.
      if (ballRect.x < 0) {
        BALL.directionX = 1;
      }

      // Check player paddle collision.
      var paddleRect = view.getPaddleRect();

      if (ballRect.y + ballRect.height >= paddleRect.y) {
        if (ballRect.x >= paddleRect.x && ballRect.x <= paddleRect.x + paddleRect.width) {
          BALL.directionY = -1;
        }
      }

      // Increment ball position on X and Y axes based on ball speed and orientation.
      view.setBallPos({
        left: ballRect.x + (BALL.speed * BALL.directionX),
        top: ballRect.y + (BALL.speed * BALL.directionY)
      });
    };

    // Public methods.
    this.startGame = function() {
      console.log(".c:startGame");
      _updateInterval = setInterval(updateGame, GAME.gameFps);
    };

    this.stopGame = function() {
      console.log(".c:stopGame");
      clearInterval(_updateInterval);
    };

    // Bindings.

  }
});

// Lets rock.
$(function(){
  $("#pageGameContent").css("padding", "0");

  var gameController = new $.Controller(new $.Field($("#playground")), new $.Model());

  function onPageChange(event, ui) {
    if (event.type == "pageshow") {
      gameController.startGame();
    } else {
      gameController.stopGame()
    }
  };

  $("#pageGame").live("pageshow", onPageChange);
  $("#pageGame").live("pagehide", onPageChange);
});
